package cn.edu.zut.sunday.cve.controller;


import cn.edu.zut.sunday.base.controller.GenericController;
import cn.edu.zut.sunday.cve.domain.InfoSec;
import cn.edu.zut.sunday.cve.service.impl.InfoService;
import cn.edu.zut.sunday.misc.vo.InformationQuery;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.criteria.Predicate;
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Api("cve-信息安全数据接口")
@Slf4j
@RestController
@RequestMapping("cve/infosec")
public class InfoSeController extends GenericController<InfoSec, Integer, InfoService> {

    @Autowired
    public void setInfoService(InfoService infoService) {
        this.service = infoService;
    }

    @Override
    protected InfoSec addModelCheck(InfoSec model, javax.servlet.http.HttpServletRequest request) {
        return null;
    }

    @Override
    protected Pageable createPageable(int page, int size) {
        Sort sort = Sort.by(Sort.Direction.DESC, "published");
        return PageRequest.of(page, size, sort);
    }

    @Override
    protected Specification<InfoSec> createSpecification(String requestBodyStr) {
        log.info("requestBodyStr: {}", requestBodyStr);
        final InformationQuery informationQuery = new Gson().fromJson(requestBodyStr,
          InformationQuery.class);
        log.info("InformationQuery: {}", informationQuery);

        if (informationQuery != null) {
            return getInfoSecSpecification(informationQuery);
        }
        return null;
    }


    private Specification<InfoSec> getInfoSecSpecification(InformationQuery informationQuery) {

        String name      = informationQuery.getName();
        String severity  = informationQuery.getSeverity();
        String vulnType = informationQuery.getVulnType();
        Specification<InfoSec> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            if (!StringUtils.isEmpty(name)) {
                Predicate p1 = criteriaBuilder.like(root.get("name"), sqlLike(name));
                list.add(p1);
            }

            if (!StringUtils.isEmpty(severity)) {
                // 此处为查询serverName中含有key的数据
                Predicate p2 = criteriaBuilder.like(root.get("severity"), sqlLike(severity));
                list.add(p2);
            }
            if (!StringUtils.isEmpty(vulnType)) {
                // 此处为查询serverName中含有key的数据
                Predicate p2 = criteriaBuilder.like(root.get("vulnType"), sqlLike(vulnType));
                list.add(p2);
            }

            return criteriaBuilder.and(list.toArray(new Predicate[0]));
        };

        return specification;
    }

    //增加方法
    @Override
    public InfoSec add(@RequestBody InfoSec infoSec,
      HttpServletRequest request) {
        if (infoSec == null) {
            return null;
        }
        infoSec = setCommonAttr(infoSec, true);
        infoSec = this.service.save(infoSec);
        return infoSec;
    }

    //修改方法
    @Override
    public InfoSec update(@PathVariable Integer id, @RequestBody InfoSec infoSec,
      HttpServletRequest request) {
        infoSec.setId(id);
        infoSec = setCommonAttr(infoSec, false);
        infoSec = this.service.save(infoSec);
        return infoSec;
    }

    //删除方法
    @Override
    public void delete(@PathVariable Integer id) {

        this.service.delete(id);
    }
  //根据id查找方法
    public InfoSec findById(@PathVariable Integer id) {

        return this.service.findById(id);
    }
}


